package com.atguigu.gmall.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.HttpClientUtil;
import com.atguigu.gmall.constant.MqConst;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.mapper.CartInfoForOrderMapper;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.service.RabbitService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.netty.handler.codec.json.JsonObjectDecoder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class OrderInfoServiceImpl implements OrderInfoService {


    @Value("${ware.url}")
    private String wareUrl;

    //判断仓库项目那边是否有货
    @Override
    public boolean hasStock(Long skuId, Integer skuNum) {
        //远程连接  Feign   没有Nacos注册中心的时候
        //直接使用Http请求
        String url = wareUrl + "/hasStock?skuId=" + skuId + "&num=" + skuNum;
        return "1".equals(HttpClientUtil.doGet(url));
    }

    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private CartInfoForOrderMapper cartInfoForOrderMapper;

    //保存订单 订单详情  删除购物车已经选中的商品
    @Override
    @Transactional
    public Long insertOrder(OrderInfo orderInfo) {

        //1:  保存订单
        //总金额
        orderInfo.sumTotalAmount();
        //订单状态
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());
        //订单交易编号 交互的时候 传递 唯一 Shift +Ctrl + u
        // 一毫秒内 会不会生产200张以上订单
        String outTradeNo = "ATGUIGU" + System.currentTimeMillis()
                + orderInfo.getUserId();
        //new Random().nextInt(1000);//0~999
        orderInfo.setOutTradeNo(outTradeNo);
        // 获取订单明细
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        StringBuffer tradeBody = new StringBuffer();
        for (OrderDetail orderDetail : orderDetailList) {
            tradeBody.append(orderDetail.getSkuName() + " ");
        }
        if (tradeBody.toString().length() > 100) {
            orderInfo.setTradeBody(tradeBody.toString().substring(0, 100));
        } else {
            orderInfo.setTradeBody(tradeBody.toString());
        }
        //订单创建时间
        orderInfo.setCreateTime(new Date());
        //失效时间
        Calendar calendar = Calendar.getInstance();
        //当前时间基本之上 追加时间
        calendar.add(Calendar.MINUTE, 130);//支付宝默认情况下 二维码有效期为2小时
        Date time = calendar.getTime();//14:33  16:33
        orderInfo.setExpireTime(time);
        //订单进度
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());
        //图片
        orderInfo.setImgUrl(orderDetailList.get(0).getImgUrl());
        //Mybatis Plus 返回值 Id
        orderInfoMapper.insert(orderInfo);

        List<String> skuIds = new ArrayList<>();
        //2;  订单详情
        for (OrderDetail orderDetail : orderDetailList) {
            orderDetail.setOrderId(orderInfo.getId());
            orderDetailMapper.insert(orderDetail);
            skuIds.add(orderDetail.getSkuId().toString());
        }

        //删除DB中购物车
        // delete  from 表  where sku_id in (1,2,3) and user_id = 3    Mybatis Plus
/*        cartInfoForOrderMapper.delete(new QueryWrapper<CartInfo>()
          .in("sku_id",skuIds).eq("user_id",orderInfo.getUserId()));
        String cacheKey = RedisConst.USER_KEY_PREFIX + orderInfo.getUserId()
                + RedisConst.USER_CART_KEY_SUFFIX;
        //3: 删除购物车已经选中的商品 canal
        redisTemplate.opsForHash().delete(cacheKey, skuIds.toArray());*/

      /*  rabbitService.sendDelayMessagePlugins(MqConst.EXCHANGE_DIRECT_ORDER_CANCEL,
                MqConst.ROUTING_ORDER_CANCEL,orderInfo.getId(),10);*/
        //返回值
        return orderInfo.getId();
    }

    @Override
    public OrderInfo getOrderInfo(Long orderId) {
        return orderInfoMapper.selectById(orderId);
    }

    //查询订单及订单详情
    public OrderInfo getOrderInfoAndDetail(Long orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        orderInfo.setOrderDetailList(orderDetailMapper.selectList(
                new QueryWrapper<OrderDetail>()
                        .eq("order_id", orderId)));
        return orderInfo;
    }

    //发消息 库存管理微服务那边  扣库存
    @Override
    public void sendOrderStatus(Long id) {

        //1：查询订单对象
        OrderInfo orderInfo = getOrderInfoAndDetail(id);
        //2：准备发给仓库那边的数据
        Map map = initWareOrder(orderInfo);

        rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_WARE_STOCK,
                MqConst.ROUTING_WARE_STOCK, JSON.toJSONString(map));
    }

    //拆单 开始了
    @Override
    public List<OrderInfo> orderSplit(Long orderId, String wareSkuMap) {
        //1: order_info   原订单ID 9  二个订单 10，11
        //wareSkuMap   [{"wareId":"1","skuIds":["9"]},{"wareId":"2","skuIds":["15"]}]
        //原始订单
        OrderInfo originOrderInfo = getOrderInfoAndDetail(orderId);
        //转集合Map
        List<Map> mapList = JSONObject.parseArray(wareSkuMap, Map.class);

        List<OrderInfo> subOrderInfoList = new ArrayList<>();

        for (Map map : mapList) {
            //{"wareId":"1","skuIds":["9"]}
            //仓库ID
            String wareId = (String) map.get("wareId");

            //保存新订单
            OrderInfo subOrderInfo = new OrderInfo();
            BeanUtils.copyProperties(originOrderInfo, subOrderInfo);
            //ID  不要
            subOrderInfo.setId(null);
            //父ID
            subOrderInfo.setParentOrderId(originOrderInfo.getId());
            //仓库ID
            subOrderInfo.setWareId(wareId);

            //订单详情表   //{"wareId":"1","skuIds":["9"]}
            List<OrderDetail> orderDetailList = originOrderInfo.getOrderDetailList();
            //此仓库对应的商品集合  "skuIds":["9"]
            List<String> skuIds = (List<String>) map.get("skuIds");

            //最新订单详情集合
            List<OrderDetail> subOrderDetails = orderDetailList.stream().filter(orderDetail -> {
                return skuIds.contains(orderDetail.getSkuId().toString());
            }).collect(Collectors.toList());
            subOrderInfo.setOrderDetailList(subOrderDetails);
            //总金额
            subOrderInfo.sumTotalAmount();
            //保存订单及订单详情
            saveOrderInfo(subOrderInfo);
            subOrderInfoList.add(subOrderInfo);
        }
        //原始订单 是父亲了   进度状态 是拆单状态
        updateOrderStatus(orderId, ProcessStatus.SPLIT);
        //拆单后订单集合（每一个订单里面又有订单详情集合）
        return subOrderInfoList;
    }

    public void updateOrderStatus(Long orderId, ProcessStatus split) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(orderId);
        orderInfo.setProcessStatus(split.name());
        orderInfoMapper.updateById(orderInfo);
    }

    private void saveOrderInfo(OrderInfo subOrderInfo) {
        orderInfoMapper.insert(subOrderInfo);
        for (OrderDetail orderDetail : subOrderInfo.getOrderDetailList()) {
            orderDetail.setOrderId(subOrderInfo.getId());
            orderDetailMapper.insert(orderDetail);
        }
    }


    //准备发给仓库那边的数据
    public Map initWareOrder(OrderInfo orderInfo) {
        HashMap map = new HashMap();
        map.put("orderId", orderInfo.getId());
        map.put("consignee", orderInfo.getConsignee());
        map.put("consigneeTel", orderInfo.getConsigneeTel());
        map.put("orderComment", orderInfo.getOrderComment());
        map.put("orderBody", orderInfo.getTradeBody());
        map.put("deliveryAddress", orderInfo.getDeliveryAddress());
        map.put("paymentWay", "2");
        //仓库ID
        map.put("wareId",orderInfo.getWareId());

        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        ArrayList<Map> mapArrayList = new ArrayList<>();
        for (OrderDetail orderDetail : orderDetailList) {
            HashMap hashMap = new HashMap();
            hashMap.put("skuId", orderDetail.getSkuId());
            hashMap.put("skuNum", orderDetail.getSkuNum());
            hashMap.put("skuName", orderDetail.getSkuName());
            mapArrayList.add(hashMap);
        }
        map.put("details", mapArrayList);
        return map;
    }

    @Autowired
    private RabbitService rabbitService;

    public static void main(String[] args) {
        System.out.println(OrderStatus.UNPAID.name());
    }
}
